package com.cms.server.resolver.plugins.submit;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import com.efounder.builder.base.data.DataSetUtils;
import com.efounder.builder.base.data.EFDataSet;
import com.efounder.builder.base.data.EFRowSet;
import com.efounder.builder.base.data.ESPRowSet;
import com.efounder.eai.data.JParamObject;
import com.efounder.form.EFFormDataModel;
import com.efounder.form.io.FormDataResolverAdapter;
import com.efounder.form.server.resolver.util.SYS_MDL_VAL;
import com.efounder.sql.JStatement;
import com.metadata.bizmodel.SYS_MODEL;
import com.persistence.FLOW_TASK_LIST;

/**
 * 1.流程节点提交，如果下个节点是会签节点，则跳过不处理，在下个插件里处理
 * 2.流程节点取回，如果本节点是会签节点，则跳过不处理，在下个插件里处理
 * 3.流程节点退回，如果退回到会签节点，则跳过不处理，在下个插件里处理
 * @author Administrator
 *
 */
public class CMSSubmitToCountersignNode extends FormDataResolverAdapter {

	//初始化FormDataModel
	public void finishSaveForm(JStatement stmt, EFFormDataModel model, JParamObject PO) throws Exception {
		EFDataSet                    billDataSet = model.getBillDataSet();
		EFRowSet                      itemRowSet = null;
		EFDataSet                    itemDataSet = null;
		EFDataSet                     flowNodeDS = null;
		EFDataSet                      BMDataset = EFDataSet.getInstance(new String[]{"F_BMBH"});
		EFDataSet                 invalidDataset = EFDataSet.getInstance();
		EFDataSet  countersignPreNodeFlowDataSet = null;
		EFRowSet                        BMRowSet = null;
		EFRowSet                      flowRowset = EFRowSet.getInstance();
		EFRowSet                      nodeRowset = EFRowSet.getInstance();
		EFRowSet                  nextNodeRowset = EFRowSet.getInstance();
		EFRowSet                  pendingRowset = EFRowSet.getInstance();
		String                            strSql = "";
		String                   strHQDataSetKey = "";		//会签节点对应的单据分录数据集KEY
		ResultSet                             rs = null;
		java.util.List<String>    dataSetKeyList = new java.util.ArrayList<String>();//单据分录数据集KEY
		long                             curTime = new Date().getTime();
		String                            F_KJQJ = billDataSet.getRowSet(0).getString(PO.GetValueByParamName(SYS_MODEL._BLFL_KJQJ_COL_, SYS_MDL_VAL.BILL_KJQJ), "");
		String                            F_GUID = billDataSet.getRowSet(0).getString(PO.GetValueByParamName(SYS_MODEL._BILL_GUID_COL_, SYS_MDL_VAL.BILL_GUID), "");
		String                            F_DJBH = billDataSet.getRowSet(0).getString(PO.GetValueByParamName(SYS_MODEL._BILL_BH_COL_, SYS_MDL_VAL.BILL_BH), null);
		String                           FLOW_ID = PO.GetValueByParamName(FLOW_TASK_LIST._FLOW_ID, "");
		String                     RESR_IN_CAUSE = PO.GetValueByParamName(FLOW_TASK_LIST._RESR_IN_CAUSE, "");

		//获取分录数据集的KEY
		if(billDataSet.getRowCount() > 0) {
			itemRowSet = billDataSet.getRowSet(0);
			dataSetKeyList = itemRowSet.getDataSetKeyList();
		}
		
		//查询部门
		strSql = " select F_BMBH, F_BMMC from HYBMZD where F_SYZT = '1'";
		rs = stmt.executeQuery(strSql);
		BMDataset = DataSetUtils.resultSet2DataSet(rs, BMDataset);
		
		//如果不是提交操作，则返回
		if(!RESR_IN_CAUSE.equals("submit")) return;
		
		//获取流程节点
		strSql = "select * from FLOW_TASK_LIST where BIZ_DATE = '" + F_KJQJ + "' and BIZ_DJBH = '" + F_DJBH + "' and "
		       + " FLOW_ID = '" + FLOW_ID + "' and NODE_TAG = '" + PO.GetValueByParamName(FLOW_TASK_LIST._OP_NODE, "") + "' order by OP_ID DESC";
		rs = stmt.executeQuery(strSql);
		flowNodeDS = DataSetUtils.resultSet2DataSet(rs, flowNodeDS);
		
		//获取提交到节点名称
		strSql = "select * from FLOW_NODE_LIST where FLOW_ID ='" + FLOW_ID + "' and NODE_ID = '" + PO.GetValueByParamName(FLOW_TASK_LIST._OP_NODE, "") + "'";
		rs = stmt.executeQuery(strSql);
		if(rs != null && rs.next()) nodeRowset = (EFRowSet) DataSetUtils.resultSet2RowSet(rs, nodeRowset);
		
		//如果是结束节点，则返回
		if(nodeRowset.getString("NODE_TYPE", "").equals("end")) return;
		
		strSql = "select * from FLOW_NODE_LIST where FLOW_ID ='" + FLOW_ID + "' and NODE_ID = '" + nodeRowset.getString("NODE_NEXT", "") + "'";
		rs = stmt.executeQuery(strSql);
		if(rs != null && rs.next()) {
			nextNodeRowset = (EFRowSet) DataSetUtils.resultSet2RowSet(rs, nextNodeRowset);
			//如果下个节点不是会签节点，则直接返回
			if(!nextNodeRowset.getString("NODE_TYPE", "").equals("countersign")) {
				return;
			} 
			//如果是会签节点，则从节点的扩展属性里查找单据分录要取的数据集
			else {
				PO.SetValueByParamName("NODE_NEXT", nodeRowset.getString("NODE_NEXT", ""));
				strSql = "select * from FLOW_NODE_ATTR where FLOW_ID ='" + FLOW_ID + "' and NODE_ID = '" + nodeRowset.getString("NODE_NEXT", "") + "' and ATTR_KEY = 'HQDataSetKey'";
				rs = stmt.executeQuery(strSql);
				//如果定义了要取的数据集KEY
				if(rs != null && rs.next()) {
					strHQDataSetKey = rs.getString("ATTR_VAL");
				} 
				//如果没有定义，则默认取第一个
				else {
					if(dataSetKeyList.size() > 0) strHQDataSetKey = dataSetKeyList.get(0);
				}
			}
			//获取分录数据集
			itemDataSet = itemRowSet.getDataSet(strHQDataSetKey);
		}
		
//		//更新上一个任务节点的状态
//		strSql = "update FLOW_TASK_LIST set RESR_STATUS = 'processed', RESR_OUT_CAUSE = '" + PO.GetValueByParamName(FLOW_TASK_LIST._RESR_OUT_CAUSE, "") + "'"
//			   + " where OP_ID = '" + flowRowset.getString("OP_ID", "") + "' and FLOW_ID = '" + FLOW_ID + "'";
//		stmt.execute(strSql);
		
		//modify by prayer 2014-10-13 生产通知单由于多个部门同时退回到第一个编制节点，在编制节点统一修改后，一块提交，不能按照原来的方式处理
		
		//查找编辑节点是否有待办的该部门节点
		countersignPreNodeFlowDataSet = getCountersignPreNodeFlowList(PO, stmt, F_KJQJ, F_DJBH, FLOW_ID);
		//流程节点不在部门分录中，说明之前的部门已经删除，改流程节点作废
		invalidDataset = loadInvalidBM(countersignPreNodeFlowDataSet, itemDataSet);
		
		if(invalidDataset.getRowCount() > 0) {
			flowRowset = invalidDataset.getRowSet(0);
		} else {
			flowRowset = flowNodeDS.getRowSet(0);
		}
		//循环分录数据集
		for(int i = 0; i < itemDataSet.getRowCount(); i++) {
			curTime++;
			itemRowSet = itemDataSet.getRowSet(i);
			//检查该部门如果已经在会签节点待审批，或者已经进入了等待状态，则不允许添加、修改
			boolean bCanAdd = checkCanAddBMItem(itemRowSet, PO, stmt, F_KJQJ, F_DJBH, FLOW_ID);
			
			if(!bCanAdd) {
				continue;
			} else {
//				//会签节点和下一个节点都没有该部门流程信息，则去上个节点查找
//				rowset = getPendingFlow(stmt, itemRowSet.getString("F_BMBH", ""), F_KJQJ, F_DJBH, PO.GetValueByParamName(FLOW_TASK_LIST._OP_NODE, ""), FLOW_ID);
//				//存在退回的部门节点流程，需要更新上个节点任务
//				if(rowset != null) {
//					//更新上一个任务节点的状态
//					strSql = "update FLOW_TASK_LIST set RESR_STATUS = 'processed', RESR_OUT_CAUSE = '" + PO.GetValueByParamName(FLOW_TASK_LIST._RESR_OUT_CAUSE, "") + "'"
//						   + " where OP_ID = '" + rowset.getString("OP_ID", "") + "' and FLOW_ID = '" + FLOW_ID + "'";
//					stmt.execute(strSql);
//				} 
				//更新上一个任务节点的状态
				//会签节点和下一个节点都没有该部门流程信息，则去上个节点查找,比如退回后，另一个部门不变，则作废的分录更新为invalid状态，不变的分录还是更新为submit
				pendingRowset = getPendingFlow(stmt, itemRowSet.getString("F_BMBH", ""), F_KJQJ, F_DJBH, PO.GetValueByParamName(FLOW_TASK_LIST._OP_NODE, ""), FLOW_ID);
				if(pendingRowset != null) {
					strSql = "update FLOW_TASK_LIST set RESR_STATUS = 'processed', RESR_OUT_CAUSE = '" + PO.GetValueByParamName(FLOW_TASK_LIST._RESR_OUT_CAUSE, "") + "'"
					       + " where OP_ID = '" + pendingRowset.getString("OP_ID", "") + "' and FLOW_ID = '" + FLOW_ID + "'";
					stmt.execute(strSql);
				} else {
					strSql = "update FLOW_TASK_LIST set RESR_STATUS = 'processed', RESR_OUT_CAUSE = '" + PO.GetValueByParamName(FLOW_TASK_LIST._RESR_OUT_CAUSE, "") + "'"
					       + " where OP_ID = '" + flowRowset.getString("OP_ID", "") + "' and FLOW_ID = '" + FLOW_ID + "'";
					stmt.execute(strSql);
				}
				
				//如果rowset为null说明是新添加的部门节点，否则为在原先部门上修改的
				//如果多个部门同时提交，时间可能一样，所以为了防止插入引起主键重复，所以加1
				BMRowSet = (EFRowSet) BMDataset.getRowSet(itemRowSet.getString("F_BMBH", ""));
				strSql = "insert into FLOW_TASK_LIST (OP_ID,FLOW_ID,BIZ_DJBH,BIZ_DATE,BIZ_GUID,OP_USER,OP_USER_NAME,OP_TIME,"
					   + "OP_BMBH,OP_NOTE,TASK_STATUS,OP_NODE,NODE_SRC,NODE_SRC_NAME,NODE_TAG,NODE_TAG_NAME,POP_ID,RESR_STATUS,TASK_TO_UNIT,TASK_TO_UNIT_NAME," ;
			 	
				for(int j = 1; j <= 20; j++) {
					if(j < 10) {
						if(PO.GetValueByParamName(FLOW_TASK_LIST._F_CHAR + "0" + j, null) != null) {
							strSql += "F_CHAR0" + j + ",";
						}
						if(PO.GetValueByParamName(FLOW_TASK_LIST._F_DATE + "0" + j, null) != null) {
							strSql += "F_DATE0" + j + ",";
						}
						if(PO.GetValueByParamName(FLOW_TASK_LIST._F_NUM + "0" + j, null) != null) {
							strSql += "F_NUM0" + j + ",";
						}
					} else {
						if(PO.GetValueByParamName(FLOW_TASK_LIST._F_CHAR + j, null) != null) {
							strSql += "F_CHAR" + j + ",";
						}
						if(PO.GetValueByParamName(FLOW_TASK_LIST._F_DATE + j, null) != null) {
							strSql += "F_DATE" + j + ",";
						}
						if(PO.GetValueByParamName(FLOW_TASK_LIST._F_NUM + j, null) != null) {
							strSql += "F_NUM" + j + ",";
						}
					}
				}
			 	strSql += "RESR_IN_CAUSE,RESR_OUT_CAUSE) values ('"
			 	        + curTime + "', '" + PO.GetValueByParamName(FLOW_TASK_LIST._FLOW_ID, "") + "', '"
						+ F_DJBH + "', '" + F_KJQJ + "', '" + F_GUID + "', '" + PO.GetValueByParamName(FLOW_TASK_LIST._OP_USER, "")
						+ "', '" + PO.GetValueByParamName(FLOW_TASK_LIST._OP_USER_NAME, "") + "', '"
						+ curTime + "', '" + PO.GetValueByParamName(FLOW_TASK_LIST._OP_BMBH, "") + "', '" 
						+ PO.GetValueByParamName(FLOW_TASK_LIST._OP_NOTE, "") + "', 'processing', '"
						+ PO.GetValueByParamName(FLOW_TASK_LIST._OP_NODE, "") + "', '" + nodeRowset.getString("NODE_ID", "") + "', '"
						+ nodeRowset.getString("NODE_NAME", "") + "', '" + nextNodeRowset.getString("NODE_ID", "") + "', '" + nextNodeRowset.getString("NODE_NAME", "") 
						+ "', '" + flowRowset.getString("OP_ID", "") + "', '" + PO.GetValueByParamName(FLOW_TASK_LIST._RESR_STATUS, "") 
						+ "','" + itemRowSet.getString("F_BMBH", "") + "','" + BMRowSet.getString("F_BMMC", "") + "',";
			 	for(int j = 1; j <= 20; j++) {
			 		if(j < 10) {
			 			if(PO.GetValueByParamName(FLOW_TASK_LIST._F_CHAR + "0" + j, null) != null) {
			 				strSql += "'" + PO.GetValueByParamName(FLOW_TASK_LIST._F_CHAR + "0" + j, null)  + "',";
			 			} 
			 			if(PO.GetValueByParamName(FLOW_TASK_LIST._F_DATE + "0" + j, null) != null) {
			 				strSql += "'" + PO.GetValueByParamName(FLOW_TASK_LIST._F_DATE + "0" + j, null)  + "',";
			 			}
			 			if(PO.GetValueByParamName(FLOW_TASK_LIST._F_NUM + "0" + j, null) != null) {
			 				strSql += "'" + PO.GetValueByParamName(FLOW_TASK_LIST._F_NUM + "0" + j, null)  + "',";
			 			}
			 		} else {
			 			if(j == 19 && PO.GetValueByParamName(FLOW_TASK_LIST._F_CHAR + j, null) != null) {
			 				strSql += "'" + itemRowSet.getString("F_BMBH", "")  + "',";
			 			} else if(j == 20 && PO.GetValueByParamName(FLOW_TASK_LIST._F_CHAR + j, null) != null) {
			 				strSql += "'" + itemRowSet.getString("F_BMMC", "")  + "',";
			 			} else {
			 				if(PO.GetValueByParamName(FLOW_TASK_LIST._F_CHAR + j, null) != null) {
				 				strSql += "'" + PO.GetValueByParamName(FLOW_TASK_LIST._F_CHAR + j, null)  + "',";
				 			}
			 			}
			 			
			 			if(PO.GetValueByParamName(FLOW_TASK_LIST._F_DATE + j, null) != null) {
			 				strSql += "'" + PO.GetValueByParamName(FLOW_TASK_LIST._F_DATE + j, null)  + "',";
			 			}
			 			if(PO.GetValueByParamName(FLOW_TASK_LIST._F_NUM + j, null) != null) {
			 				strSql += "'" + PO.GetValueByParamName(FLOW_TASK_LIST._F_NUM + j, null)  + "',";
			 			}
			 		}
			 	}
			 	strSql += "'" + PO.GetValueByParamName(FLOW_TASK_LIST._RESR_IN_CAUSE, "") + "', '')";
			 	stmt.execute(strSql);
			}		    
		}
		
		for(int i = 0; i < invalidDataset.getRowCount(); i++) {
			strSql = "update FLOW_TASK_LIST set RESR_STATUS = 'processed', RESR_OUT_CAUSE = 'invalid'"
			       + " where OP_ID = '" + invalidDataset.getRowSet(i).getString("OP_ID", "") + "' and FLOW_ID = '" + FLOW_ID + "'";
			stmt.execute(strSql);
		}
	 	PO.SetValueByParamName(FLOW_TASK_LIST._OP_ID, String.valueOf(curTime));
//	 	PO.SetValueByParamName(FLOW_TASK_LIST._OP_NODE, nodeRowset.getString("NODE_ID", ""));
	 	PO.SetValueByParamName("OP_NODE_NEXT", nextNodeRowset.getString("NODE_ID", ""));
	}
	
	//每次取到一条部门单据分录，就从代办流程里查找
	private EFRowSet getBMItemCorrespondingFlowRow(JStatement stmt, String OP_ID, String FLOW_ID) throws Exception {
		ResultSet  rs = null;
		String strSql = "";
		EFDataSet   flowNodeDS = null;
		
		//获取流程节点
		//获取流程节点
		strSql = "select * from FLOW_TASK_LIST where OP_ID = '" + OP_ID + "' and FLOW_ID = '" + FLOW_ID + "' order by OP_ID DESC";
		rs = stmt.executeQuery(strSql);
		flowNodeDS = DataSetUtils.resultSet2DataSet(rs, flowNodeDS);
		if(flowNodeDS != null && flowNodeDS.getRowCount() > 0) {
			return flowNodeDS.getRowSet(0);
		} else {
			return null;
		}
	}
	
	//每次取到一条部门单据分录，就从代办流程里查找
		
	private EFRowSet getPendingFlow(JStatement stmt, String F_BMBH, String F_KJQJ, String F_DJBH, String NODE_ID, String FLOW_ID) throws Exception {
		String          strSql = "";
		EFDataSet   flowNodeDS = null;
		ResultSet           rs = null;
		
		//获取流程节点
		//获取流程节点
		strSql = "select * from FLOW_TASK_LIST where FLOW_ID = '" + FLOW_ID + "' and NODE_TAG = '" + NODE_ID + "' and F_CHAR19 = '" + F_BMBH 
		       + "' and BIZ_DJBH = '" + F_DJBH + "' order by OP_ID DESC";
		rs = stmt.executeQuery(strSql);
		flowNodeDS = DataSetUtils.resultSet2DataSet(rs, flowNodeDS);
		if(flowNodeDS != null && flowNodeDS.getRowCount() > 0) {
			return flowNodeDS.getRowSet(0);
		} else {
			return null;
		}
	}
	
	//每次取到一条部门单据分录，就从代办流程里查找是否有该部门，没有的话就添加一条部门流程节点，有的话就直接跳过
	private boolean checkCanAddBMItem(EFRowSet bmItemRowSet, JParamObject PO, JStatement stmt, String F_KJQJ, String F_DJBH, String FLOW_ID) throws Exception {
		ResultSet  rs = null;
		String strSql = "";
		EFDataSet   flowNodeDS = null;
		
		//获取流程节点
		//存在两种情况，这两种情况，不需要添加
		//1、待部门会签节点审批NODE_SRC=N1，NODE_TAG=N2,RESR_STATUS=pending，F_CHAR19='',TASK_TO_UNIT=001;002
		//2、001部门确认审批后，进入等待节点，NODE_SRC=N2，NODE_TAG=N3，RESR_STATUS=waiting,F_CHAR19=001，TASK_TO_UNIT=''
		strSql = "select * from FLOW_TASK_LIST where BIZ_DATE = '" + F_KJQJ + "' and BIZ_DJBH = '" + F_DJBH + "' and "
		       + " FLOW_ID = '" + FLOW_ID + "' and "
		       + " ((TASK_TO_UNIT = '" + bmItemRowSet.getString("F_BMBH", "") + "' and RESR_STATUS = 'pending' and NODE_TAG = '" + PO.GetValueByParamName("NODE_NEXT", "") + "') or "//第一种情况
		       + " (F_CHAR19 = '" + bmItemRowSet.getString("F_BMBH", "") + "' and RESR_STATUS = 'waiting' and NODE_SRC = '" + PO.GetValueByParamName("NODE_NEXT", "") + "')) "
		       + " order by OP_ID DESC";//第二种情况
		rs = stmt.executeQuery(strSql);
		flowNodeDS = DataSetUtils.resultSet2DataSet(rs, flowNodeDS);
		//如果存在，说明该部门已经在等待审批或者进入等待状态，不能添加
		if(flowNodeDS != null && flowNodeDS.getRowCount() > 0) {
			return false;
		} else {
			return true;
		}
	}
	
	//获取在上一个节点的流程信息
	private EFDataSet getCountersignPreNodeFlowList(JParamObject PO, JStatement stmt, String F_KJQJ, String F_DJBH, String FLOW_ID) throws Exception {
		ResultSet           rs = null;
		String          strSql = "";
		EFDataSet   flowNodeDS = EFDataSet.getInstance("FLOW_TASK_LIST", new String[]{"F_BMBH"});
		ESPRowSet   flowNodeRS = null;
		String          F_BMBH = "";
		
		//如果是编制节点取回，TASK_TO_UNIT和F_CHAR19都为空，退回的F_CHAR19不为空
		strSql = "select * from FLOW_TASK_LIST where BIZ_DATE = '" + F_KJQJ + "' and BIZ_DJBH = '" + F_DJBH + "' and "
		       + " FLOW_ID = '" + FLOW_ID + "' and NODE_TAG = '" + PO.GetValueByParamName(FLOW_TASK_LIST._OP_NODE, "") + "' and "
		       + " (TASK_TO_UNIT != '' or F_CHAR19 != '') and RESR_STATUS = 'pending' "
		       + " order by OP_ID DESC";
		rs = stmt.executeQuery(strSql);
		flowNodeDS = DataSetUtils.resultSet2DataSet(rs, flowNodeDS);
		
		for(int i = 0; flowNodeDS != null && i < flowNodeDS.getRowCount(); i++) {
			
			flowNodeRS = flowNodeDS.getRowSet(i);
			F_BMBH = flowNodeRS.getString("F_CHAR19", "").trim().equals("") ? flowNodeRS.getString("TASK_TO_UNIT", "").trim() : flowNodeRS.getString("F_CHAR19", "").trim();
			flowNodeRS.putString("F_BMBH", F_BMBH);
			flowNodeDS.buildPrimeKeyIndex(flowNodeRS);
		}
		return flowNodeDS;
	}
	
	//查询作废的部门流程分录
	private EFDataSet loadInvalidBM(EFDataSet flowNodeDS, EFDataSet itemDataSet) {
		String          F_BMBH = "";
		EFRowSet    flowNodeRS = null;
		EFRowSet    itemRowSet = null;
		EFDataSet    invalidDS = EFDataSet.getInstance();
		boolean       bInvalid = false;
		for(int i = 0; i < flowNodeDS.getRowCount(); i++) {
			bInvalid = false;
			flowNodeRS = flowNodeDS.getRowSet(i);
			F_BMBH = flowNodeRS.getString("F_CHAR19", "").trim().equals("") ? flowNodeRS.getString("TASK_TO_UNIT", "").trim() : flowNodeRS.getString("F_CHAR19", "").trim();
			for(int j = 0; j < itemDataSet.getRowCount(); j++) {
				itemRowSet = itemDataSet.getRowSet(j);
				if(itemRowSet.getString("F_BMBH", "").equals(F_BMBH)) {
					bInvalid = false;
					break;
				}
				bInvalid = true;
			}
			//表示流程里某个编辑编辑代办的部门流程节点不在分录中，说明这个部门是修改后的，比如从001部门修改为002部门，那么001部门作废，002部门新添加
			//如果作废多个，则只取第一个就可以了
			if(bInvalid) {
				invalidDS.addRowSet(flowNodeRS);
			}
		}
		return invalidDS;
	}
}
